/*
 * ShaderManager.cpp
 *
 *  Created on: 04/11/2011
 *      Author: faust
 */

#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>

#include "SampleUtils.h"
#include "ShaderManager.h"
#include "Shaders.h"


bool ShaderManager::initialized = false;
ShaderManager* ShaderManager::instance = NULL;

ShaderManager* ShaderManager::getInstance()
{
	if (!initialized) {
		instance = new ShaderManager;
		initialized = true;
	}
	return instance;
}

void ShaderManager::createShaders()
{
	colorShaderID = SampleUtils::createProgramFromBuffer(colorVertexShader,
            colorFragmentShader);
	textureShaderID = SampleUtils::createProgramFromBuffer(textureVertexShader,
            textureFragmentShader);

    SampleUtils::checkGlError("ShaderManager::createShaders");

    LOG("ShaderManager::createShaders - colorShaderID: %i , textureShaderID: %i", colorShaderID, textureShaderID);
}


void ShaderManager::loadShaders()
{

	int maxAttrib;
	glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxAttrib);
	LOG("ShaderManager::loadShader - max vertex attribs: %i", maxAttrib);

	texVertexHandle        = glGetAttribLocation(textureShaderID, "vertexPosition");
	texNormalHandle        = glGetAttribLocation(textureShaderID, "vertexNormal");
	texMvpMatrixHandle     = glGetUniformLocation(textureShaderID, "modelViewProjectionMatrix");
	textureCoordHandle     = glGetAttribLocation(textureShaderID, "vertexTexCoord");
    SampleUtils::checkGlError("ShaderManager::loadShaders - Texture Shaders");

	colorVertexHandle        = glGetAttribLocation(colorShaderID, "vertexPosition");
	colorNormalHandle        = glGetAttribLocation(colorShaderID, "vertexNormal");
	colorMvpMatrixHandle     = glGetUniformLocation(colorShaderID, "modelViewProjectionMatrix");
	colorHandle 			 = glGetAttribLocation(colorShaderID, "vertexColor");
    SampleUtils::checkGlError("ShaderManager::loadShaders - Color Shaders");

}

void ShaderManager::useShader(unsigned int shaderId, Model3D* model, QCAR::Matrix44F mvpMatrix )
{
    glUseProgram(shaderId);
    SampleUtils::checkGlError("EdificacioAR renderFrame::use Program");

    if (shaderId == textureShaderID)
    {
    	//LOG("useShader - texVertexHandle: %i", texVertexHandle);
    	//LOG("useShader - texNormalHandle: %i", texNormalHandle);
    	//LOG("useShader - texCoordHandle: %i", textureCoordHandle);
    	//LOG("useShader - texMvpMatrixHandle: %i", texMvpMatrixHandle);

		glVertexAttribPointer(texVertexHandle, 3, GL_FLOAT, GL_FALSE, 0,
							 (const GLvoid*) &(model->vertices[0]));
		glVertexAttribPointer(texNormalHandle, 3, GL_FLOAT, GL_FALSE, 0,
							 (const GLvoid*) &(model->vertexNormals[0]));
		glVertexAttribPointer(textureCoordHandle, 2, GL_FLOAT, GL_FALSE, 0,
							 (const GLvoid*) &(model->texCoords[0]));
		glUniformMatrix4fv(texMvpMatrixHandle, 1, GL_FALSE,
						   (GLfloat*)&mvpMatrix.data[0] );

		glEnableVertexAttribArray(texVertexHandle);
		glEnableVertexAttribArray(texNormalHandle);
		glEnableVertexAttribArray(textureCoordHandle);

	    SampleUtils::checkGlError("ShaderManager::useShader - Texture Shaders");
    }
    else if (shaderId = colorShaderID)
    {
    	//LOG("useShader - colorVercolorHandle: %i", colorVercolorHandle);
    	//LOG("useShader - colorNormalHandle: %i", colorNormalHandle);
    	//LOG("useShader - colorHandle: %i", colorHandle);
    	//LOG("useShader - colorMvpMatrixHandle: %i", colorMvpMatrixHandle);

		glVertexAttribPointer(colorVertexHandle, 3, GL_FLOAT, GL_FALSE, 0,
							 (const GLvoid*) &(model->vertices[0]));
		glVertexAttribPointer(colorNormalHandle, 3, GL_FLOAT, GL_FALSE, 0,
							 (const GLvoid*) &(model->vertexNormals[0]));
		glVertexAttribPointer(colorHandle, 3, GL_FLOAT, GL_FALSE, 0,
							 (const GLvoid*) &(model->colors[0]));
		glUniformMatrix4fv(colorMvpMatrixHandle, 1, GL_FALSE,
						   (GLfloat*)&mvpMatrix.data[0] );

		glEnableVertexAttribArray(colorVertexHandle);
		glEnableVertexAttribArray(colorNormalHandle);
		glEnableVertexAttribArray(colorHandle);

	    SampleUtils::checkGlError("ShaderManager::useShader - Color Shaders");
    }
    else LOG("ShaderManager::useShader - shader ID not found");



}
void ShaderManager::disableShader(unsigned int shaderId)
{
	if (shaderId == textureShaderID)
	{
		glDisableVertexAttribArray(texVertexHandle);
		glDisableVertexAttribArray(texNormalHandle);
		glDisableVertexAttribArray(textureCoordHandle);
	    SampleUtils::checkGlError("ShaderManager::disableShader - Texture Shader");
	}
	else if (shaderId = colorShaderID)
	{
		glDisableVertexAttribArray(colorVertexHandle);
		glDisableVertexAttribArray(colorNormalHandle);
		glDisableVertexAttribArray(colorHandle);
	    SampleUtils::checkGlError("ShaderManager::disableShader - Color Shader");
	}
	else LOG("ShaderManager::useShader - shader ID not found");

}
